package com.wangsh.forward.outer.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.digest.DigestUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wangsh.forward.outer.service.IServerOperOuterService;
import com.wangsh.forward.outer.service.IServerOuterService;
import com.wangsh.forward.util.ServiceCallableUtil;
import com.wangsh.webforward.common.pojo.ApiResponse;
import com.wangsh.webforward.common.pojo.ApiResponseEnum;
import com.wangsh.webforward.common.service.BaseServiceImpl;
import com.wangsh.webforward.common.util.ConstatFinalUtil;
import com.wangsh.webforward.common.util.ExecutorServiceUtil;
import com.wangsh.webforward.common.util.PageInfoUtil;

/**
 * 客户端请求的Service
 * 其他服务请求-->本服务
 * 
 * @author wangsh
 * @param <T>
 */
public class ServerOuterServiceImpl extends BaseServiceImpl implements IServerOuterService
{
	private IServerOperOuterService serverOperOuterService = new ServerOperOuterServiceImpl() ; 
	
	/**
	 * 验证加密的字符串
	 * 
	 * 加密参数;sha256(version+pubKey+私钥)
	 * 
	 * @return
	 */
	private ApiResponse<Object> verifyEncryptStr(JSONObject reqJSON)
	{
		ApiResponse<Object> apiResponse = new ApiResponse<Object>();
		String version = reqJSON.getString("version");
		String pubKey = reqJSON.getString("pubKey");
		String encryptStr = reqJSON.getString("encrypt");

		/*
		 * 为了安全,私钥不能从请求中获取,读取本地的配置文件 私钥:客户端和服务器端同时存储到配置文件中
		 */
		// priKey=abc
		String priKey = ConstatFinalUtil.CONFIG_JSON.getString("private.key");

		String encHou = DigestUtils.sha256Hex(version + pubKey + priKey);
		if (encHou.equalsIgnoreCase(encryptStr)
				|| "0".equalsIgnoreCase(ConstatFinalUtil.CONFIG_JSON.getString("version")))
		{
			/* 成功 */
			apiResponse.setCode(ApiResponseEnum.STATUS_SUCCESS.getStatus());
		} else
		{
			/* 请求非法,您在恶意攻击 */
			apiResponse.setCode(ApiResponseEnum.INFO_JSON_ATTACK.getStatus());
		}
		apiResponse.setInfo(ConstatFinalUtil.INFO_JSON.getString(apiResponse.getCode() + ""), Collections.EMPTY_MAP);
		return apiResponse;
	}

	@Override
	public ApiResponse<Object> apiVersionService(JSONObject reqJSON)
	{
		ConstatFinalUtil.SYS_LOGGER.info("--clientVersionService--");
		ApiResponse<Object> apiResponse = new ApiResponse<Object>();
		String version = reqJSON.getString("version");
		String method = reqJSON.getString("method");
		if ("requestOne".equalsIgnoreCase(method))
		{
			if ("1".equalsIgnoreCase(version))
			{
				apiResponse = this.requestOneService(reqJSON);
			} else
			{
				apiResponse.setCode(ApiResponseEnum.INFO_JSON_VERSION_ERROR.getStatus());
			}
		}else if ("requestMulti".equalsIgnoreCase(method))
		{
			if ("1".equalsIgnoreCase(version))
			{
				apiResponse = this.requestMultiService(reqJSON);
			} else
			{
				apiResponse.setCode(ApiResponseEnum.INFO_JSON_VERSION_ERROR.getStatus());
			}
		}else if("requestBatch".equalsIgnoreCase(method)) 
		{
			if ("1".equalsIgnoreCase(version))
			{
				apiResponse = this.requestBatchService(reqJSON);
			} else
			{
				apiResponse.setCode(ApiResponseEnum.INFO_JSON_VERSION_ERROR.getStatus());
			}
		} else
		{
			apiResponse.setCode(ApiResponseEnum.INFO_METHOD_ERROR.getStatus());
		}
		apiResponse.setInfo(ConstatFinalUtil.INFO_JSON.getString(apiResponse.getCode() + ""), Collections.EMPTY_MAP);
		/* 提示信息 */
		return apiResponse;
	}

	/**
	 * 单次请求
	 * 
	 * @param reqJSON
	 * @return
	 */
	public ApiResponse<Object> requestOneService(JSONObject reqJSON)
	{
		ConstatFinalUtil.SYS_LOGGER.info("--requestOneService--");
		/* 验证请求的合法性 */
		ApiResponse<Object> apiResponse = this.verifyEncryptStr(reqJSON);
		if (apiResponse.getCode() != ApiResponseEnum.STATUS_SUCCESS.getStatus())
		{
			return apiResponse;
		}
		/* 存储多个结果,Map存储 */
		Map<String, Object> dataMapJava = new HashMap<String, Object>();
		apiResponse.setDataMapJava(dataMapJava);

		Map<String, Object> dataOneMap = new HashMap<String, Object>();
		apiResponse.setDataOne(dataOneMap);

		/* 接收参数 */
		JSONObject dataReqJSON = (JSONObject) reqJSON.get("data");
		JSONObject dataResJSON = new JSONObject();
		String url = dataReqJSON.get("url") + "";
		JSONObject headerJSON = (JSONObject) dataReqJSON.get("header");
		JSONObject requestJSON = (JSONObject) dataReqJSON.get("request");
		String method = dataReqJSON.get("method") + "";

		/* 请求头 */
		Map<String, String> headerMap = ConstatFinalUtil.jsonToMap(headerJSON);
		/* 请求体 */
		Map<String, String> paramsMap = ConstatFinalUtil.jsonToMap(requestJSON);
		/* 响应内容 */
		Map<String, String> responseMap = new HashMap<String, String>();
		String response = "";
		if ("post".equalsIgnoreCase(method))
		{
			response = this.httpUtil.methodPost(url, headerMap, paramsMap, responseMap);
		} else
		{
			response = this.httpUtil.methodGet(url, headerMap, paramsMap, responseMap);
		}
		JSONObject responseResJSON = new JSONObject();
		responseResJSON.putAll(responseMap);

		/* 处理结果 */
		dataResJSON.put("response", response);
		dataResJSON.put("responseHeader", responseResJSON);

		/* 设置json的响应体 */
		apiResponse.setDataOne(dataResJSON);

		apiResponse.setInfo(ConstatFinalUtil.INFO_JSON.getString(apiResponse.getCode() + ""), Collections.EMPTY_MAP);
		/* 提示信息 */
		return apiResponse;
	}
	
	/**
	 * 同样的url,请求多次
	 * @param reqJSON
	 * @return
	 */
	private ApiResponse<Object> requestMultiService(JSONObject reqJSON)
	{
		ConstatFinalUtil.SYS_LOGGER.info("--requestMultiService--");
		/* 验证请求的合法性 */
		ApiResponse<Object> apiResponse = this.verifyEncryptStr(reqJSON);
		if (apiResponse.getCode() != ApiResponseEnum.STATUS_SUCCESS.getStatus())
		{
			return apiResponse;
		}
		/* 存储多个结果,Map存储 */
		Map<String, Object> dataMapJava = new HashMap<String, Object>();
		apiResponse.setDataMapJava(dataMapJava);

		Map<String, Object> dataOneMap = new HashMap<String, Object>();
		apiResponse.setDataOne(dataOneMap);

		/* 接收参数 */
		JSONObject dataReqJSON = (JSONObject) reqJSON.get("data");
		String totalCount = dataReqJSON.get("totalCount") + "";
		String pageSize = dataReqJSON.get("pageSize") + "";
		
		/* 根据总次数和每页多少条进行分页 */
		PageInfoUtil pageInfoUtil = new PageInfoUtil();
		pageInfoUtil.setTotalRecord(Integer.valueOf(totalCount));
		pageInfoUtil.setPageSize(Integer.valueOf(pageSize));
		
		for(int i = 1 ; i <= pageInfoUtil.getTotalPage() ; i ++ )
		{
			pageInfoUtil.setCurrentPage(i);
			int stRecord = pageInfoUtil.getCurrRecord() + 1; 
			int edRecord = pageInfoUtil.getCurrRecord() + pageInfoUtil.getPageSize()  ; 
			if(edRecord > pageInfoUtil.getTotalRecord())
			{
				edRecord = pageInfoUtil.getTotalRecord() ; 
			}
			ConstatFinalUtil.SYS_LOGGER.info("当前页:{},起始条数:{},结束条数:{},",pageInfoUtil.getCurrentPage(), stRecord, edRecord);
			/* 多线程启动 */
			ServiceCallableUtil serviceCallableUtil = new ServiceCallableUtil();
			String operType = "requestMulti" ; 
			Map<String, Object> paramsMap = new HashMap<String, Object>();
			paramsMap.put("data", dataReqJSON);
			paramsMap.put("stRecord", stRecord);
			paramsMap.put("edRecord", edRecord);
			paramsMap.put("serverOperOuterService", serverOperOuterService);
			/* 设置参数 */
			serviceCallableUtil.setOperType(operType);
			serviceCallableUtil.setParamsMap(paramsMap);
			
			/* 启动多线程 */
			ExecutorServiceUtil.submit(serviceCallableUtil);
		}
		
		/* 重置当前页 */
		pageInfoUtil.setCurrentPage(1);
		
		/* 存储分页信息 */
		dataOneMap.put("pageInfo", pageInfoUtil.toJSON());

		apiResponse.setInfo(ConstatFinalUtil.INFO_JSON.getString(apiResponse.getCode() + ""), Collections.EMPTY_MAP);
		/* 提示信息 */
		return apiResponse;
	}
	
	/**
	 * 批量json
	 * 
	 * @param reqJSON
	 * @return
	 */
	public ApiResponse<Object> requestBatchService(JSONObject reqJSON)
	{
		ConstatFinalUtil.SYS_LOGGER.info("--requestBatchService--");
		/* 验证请求的合法性 */
		ApiResponse<Object> apiResponse = this.verifyEncryptStr(reqJSON);
		if (apiResponse.getCode() != ApiResponseEnum.STATUS_SUCCESS.getStatus())
		{
			return apiResponse;
		}
		/* 存储多个结果,Map存储 */
		Map<String, Object> dataMapJava = new HashMap<String, Object>();
		apiResponse.setDataMapJava(dataMapJava);

		Map<String, Object> dataOneMap = new HashMap<String, Object>();
		apiResponse.setDataOne(dataOneMap);

		/* 接收参数 */
		JSONObject dataReqJSON = (JSONObject) reqJSON.get("data");
		JSONArray responseResArry = JSON.parseArray(dataReqJSON.get("requestList")+"");
		//dataList中的list 是dataList的值
		List<Object> list = null;
		for (int i = 0; i < responseResArry.size(); i++)
		{
		 	JSONObject dataArryJSON = JSON.parseObject(responseResArry.get(i)+"");
		 	String url = dataArryJSON.get("url") + "";
			JSONObject headerJSON = (JSONObject) dataArryJSON.get("header");
			JSONObject requestJSON = (JSONObject) dataArryJSON.get("request");
			String method = dataArryJSON.get("method") + "";
			int totalCount = 1;
			if (dataArryJSON.get("totalCount") != null)
			{
				try
				{
					totalCount = Integer.valueOf(dataArryJSON.get("totalCount") + "");
				} catch (NumberFormatException e)
				{
				}
			}

			/* 请求头 */
			Map<String, String> headerMap = ConstatFinalUtil.jsonToMap(headerJSON);
			/* 请求体 */
			Map<String, String> paramsMap = ConstatFinalUtil.jsonToMap(requestJSON);
			/* 响应内容 */
			Map<String, String> responseMap = new HashMap<String, String>();
			String response = "";
			int succedCount = 0;
			int failedCount = 0;
			/* 循环请求 */
			for (int j = 0; j < totalCount; j++)
			{
				/* 随机休眠2-->4 百毫秒 */
				ConstatFinalUtil.randSleep("fast");
				if ("post".equalsIgnoreCase(method))
				{
					response = this.httpUtil.methodPost(url, headerMap, paramsMap, responseMap);
				} else
				{
					response = this.httpUtil.methodGet(url, headerMap, paramsMap, responseMap);
				}
				
				if (!"".equalsIgnoreCase(response))
				{
					succedCount++;
				} else
				{
					failedCount++;
				}
			}
			JSONObject responseResJSON = new JSONObject();
			responseResJSON.putAll(responseMap);

			/* 处理结果 */
			if (jsonUtil.isJson(response))
			{
				dataArryJSON.put("response", JSON.parseObject(response));
			}else {
				dataArryJSON.put("response", response);
			}
			
			dataArryJSON.put("responseHeader", responseResJSON);
			/* 次数统计 */
			dataArryJSON.put("totalCount", totalCount);
			dataArryJSON.put("succedCount", succedCount);
			dataArryJSON.put("failedCount", failedCount);
			list = new ArrayList<Object>();
			list.add(dataArryJSON);
		}
		//存储apiResponse的结果
		Map<String, List<Object>> dataList= new HashMap<String, List<Object>>();
		dataList.put(ApiResponseEnum.NAME_LIST.getName(), list);
		
		/* 设置json的响应体 */
		//apiResponse.setDataOne(dataArryJSON);
		apiResponse.setDataList(dataList);
		apiResponse.setInfo(ConstatFinalUtil.INFO_JSON.getString(apiResponse.getCode() + ""), Collections.EMPTY_MAP);
		/* 提示信息 */
		return apiResponse;
	}
}
